package org.zizi.db.esql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import oracle.jdbc.OraclePreparedStatement;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;

import org.zizi.db.AbstractEasySql;
import org.zizi.db.plan.plan.OracleResultPlan;
import org.zizi.db.tool.impl.OracleEasySqlTool;

public class OracleEasySql extends AbstractEasySql
{
	private static final String LONG_ARRAY = "TYPE_LONG_ARRAY";
	private static final String STRING_ARRAY = "TYPE_STRING_ARRAY";

	public OracleEasySql()
	{
		plan = new OracleResultPlan(charset);
		tool = new OracleEasySqlTool();
	}
	
	public <T> List<T> page(Class<T> type, int offset, int limit, String sql, Object... parameters) throws Exception
	{
		log.debug("分页查询: " + sql);

		String sql2 = "select /*+ FIRST_ROWS */ * from (select esql_t1.*, rownum esql_rownum from (" + sql + ") esql_t1 where rownum <= ?) esql_t2 where esql_rownum > ?";

		int n = parameters.length;
		Object[] parameters2 = Arrays.copyOf(parameters, n + 2);
		parameters2[n] = offset + limit;
		parameters2[n + 1] = offset;

		return list(type, sql2, parameters2);
	}

	protected void setParameters(PreparedStatement ps, Object... parameters) throws Exception
	{
		int count = ps.getParameterMetaData().getParameterCount();
		for (int i = 0; i < count; i++)
		{
			Object o = parameters[i];
			
			if (o == null)
			{
				ps.setObject(i + 1,  null);
			}
			else if (o instanceof Boolean)
			{
				int v = ((Boolean)o).booleanValue() ? 1 : 0;
				ps.setInt(i + 1, v);
			}
			else if (o instanceof String)
			{
				String s = (String)o;
				if (s.isEmpty()) s = " ";
				
				ps.setString(i + 1, charset.encodeToDatabase(s));
			}
			else if (o instanceof Date)
			{
				ps.setTimestamp(i + 1, new java.sql.Timestamp(((Date) o).getTime()));
			}
			else if (o instanceof long[] || o instanceof int[])
			{
				Connection conn = ps.getConnection();
				ArrayDescriptor desc = ArrayDescriptor.createDescriptor(LONG_ARRAY, conn);
				ARRAY array = new ARRAY(desc, conn, (o instanceof int[]) ? (int[]) o : (long[]) o);
				((OraclePreparedStatement) ps).setArray(i + 1, array);
			}
			else if (o instanceof String[])
			{
				Connection conn = ps.getConnection();
				ArrayDescriptor desc = ArrayDescriptor.createDescriptor(STRING_ARRAY, conn);
				ARRAY array = new ARRAY(desc, conn, (String[]) o);
				((OraclePreparedStatement) ps).setArray(i + 1, array);
			}
			else
			{
				ps.setObject(i + 1, o);
			}
		}
	}

	public String getTableInfoSql(String table)
	{
		return "select * from " + table + " where rownum <= 1";
	}
}
